/**
 * AES-GCM 对称加密工具
 *
 * 说明：
 * - 用于对 IndexedDB 中的快照与增量进行“按需”加密/解密（可配置是否启用）。
 * - 采用浏览器 WebCrypto（SubtleCrypto）API 原生实现，性能与安全性较好。
 * - 注意：AES-GCM 需要唯一的 IV（随机向量）才能保证安全；本工具每次调用都会随机生成 12 字节 IV 并随密文一起存储。
 * - 生产环境务必替换 getKey 的实现：
 *   - 方案A（离线友好）：基于用户口令/PBKDF2/Argon2 派生密钥，仅存 salt 与参数；
 *   - 方案B（企业密钥）：服务端/KMS 下发封装的 DEK（解封后存于内存，不落盘）。
 */

/** 获取/导入 AES-GCM 256 位密钥。
 * 参数：无（示例实现使用固定原始 key，仅演示）
 * 返回：用于加解密的 CryptoKey
 */
export async function getKey(): Promise<CryptoKey> {
  // 示例：固定 key 仅供演示；生产请替换为口令派生/服务端下发（见上文）
  const raw = new TextEncoder().encode("your-32-byte-secret-your-32-byte");
  return crypto.subtle.importKey("raw", raw, "AES-GCM", false, ["encrypt", "decrypt"]);
}

/** 加密二进制数据（ArrayBuffer）。
 * @param plain 原始明文（ArrayBuffer）
 * @returns { iv: Uint8Array; data: ArrayBuffer } 随机 IV 与密文
 */
export async function encryptArrayBuffer(plain: ArrayBuffer): Promise<{ iv: Uint8Array; data: ArrayBuffer }> {
  const key = await getKey(); // 1) 获取对称密钥（示例实现）
  const iv = crypto.getRandomValues(new Uint8Array(12)); // 2) 生成随机 IV，确保每次加密唯一
  const data = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, plain); // 3) 执行加密
  return { iv, data };
}

/** 解密二进制数据（ArrayBuffer）。
 * @param iv 随机向量（12 bytes）
 * @param cipher 密文（ArrayBuffer）
 * @returns 明文 ArrayBuffer
 */
export async function decryptArrayBuffer(iv: Uint8Array, cipher: ArrayBuffer): Promise<ArrayBuffer> {
  const key = await getKey(); // 1) 获取对称密钥（与加密一致）
  // 2) 使用保存的 IV 与密文进行解密
  return crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, cipher);
}

/**
 * 将 Uint8Array 精确裁切为独立 ArrayBuffer，避免视图偏移带来的脏数据。
 */
export function toTightArrayBuffer(view: Uint8Array): ArrayBuffer {
  // 目的：切出“恰好等于视图有效区间”的独立 ArrayBuffer，避免底层 buffer 偏移导致的冗余或脏数据
  return view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength);
}


